﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.EntityFrameworkCore.Query;
using Microsoft.EntityFrameworkCore;

using Xc.DataAccess.Core;
using Xc.DataAccess.DataBase.DeviceInfos.Models;
using System.Linq.Expressions;
using AutoMapper;

namespace Xc.DataAccess.DataBase.DeviceInfos
{
    /// <summary>
    /// 设备信息服务
    /// </summary>
    public class DbDeviceInfoService<TDbContext> : IDbDeviceInfoService where TDbContext : DbContext, IDbDevice
    {
        private readonly IDbContextFactory<TDbContext> _dbContextFactory;
        private readonly IMapper mapper;
        /// <summary>
        /// 设备信息服务
        /// </summary>
        /// <param name="dbContextFactory"></param>
        public DbDeviceInfoService(IDbContextFactory<TDbContext> dbContextFactory, IMapper mapper)
        {
            _dbContextFactory = dbContextFactory;
            this.mapper = mapper;
        }
        /// <summary>
        /// 查询设备信息
        /// </summary>
        /// <param name="callBack"></param>
        /// <returns></returns>
        public ResultData<IEnumerable<DeviceInfo>> Get(Func<IQueryable<DeviceInfo>, IQueryable<DeviceInfo>> callBack)
        {
            var db = _dbContextFactory.CreateDbContext();
            IQueryable<DeviceInfo> info= db.DeviceInfos.Include(p=>p.PropertyInfos).Include(p=>p.AlarmInfos).Where(p => p.IsDelete == false);
            var res = callBack.Invoke(info);
            return ResultData<IEnumerable<DeviceInfo>>.Accept("查询成功", res);
        }
        /// <summary>
        /// 更新设备信息
        /// </summary>
        /// <param name="deviceInfo"></param>
        /// <returns></returns>
        public Result Update(params DeviceInfoAdd[] deviceInfo)
        {
            using var db = _dbContextFactory.CreateDbContext();
            db.UpdateRange(deviceInfo.Select(p=>mapper.Map<DeviceInfo>(p)));
            return Result.From(db.SaveChanges(), s => s > 0);
        }
        /// <summary>
        /// 添加并更新设备信息
        /// </summary>
        /// <param name="deviceInfo"></param>
        /// <returns></returns>
        public Result AddUpdate(params DeviceInfoAdd[] deviceInfo)
        {
            using var db = _dbContextFactory.CreateDbContext();
            foreach (var item in deviceInfo)
            {
                var info=   db.DeviceInfos.Find(item.Id);
                if (info is null)
                {
                    var add=  mapper.Map<DeviceInfo>(item);
                    add.IsDelete = false;
                    db.DeviceInfos.Add(add);
                }
                else
                {
                    db.DeviceInfos.Update(info);
                }
            }
            return Result.From(db.SaveChanges(), s => s > 0);
        }
        /// <summary>
        /// 添加设备信息
        /// </summary>
        /// <param name="deviceInfo"></param>
        /// <returns></returns>
        public  Result Add(params DeviceInfoAdd[] deviceInfo)
        {
            try
            {
                using var db = _dbContextFactory.CreateDbContext();
                db.AddRange(deviceInfo.Select(p =>
                {
                    var data = mapper.Map<DeviceInfo>(p);
                    data.IsDelete = false;
                    return data;
                }));
                return Result.From(db.SaveChanges(), s => s > 0);
            }
            catch (DbUpdateException err)
            {
                return Result.Reject($"设备编号已被注册过,请使用其他编号");
            }

        }
        /// <summary>
        /// 删除设备
        /// </summary>
        /// <param name="deviceid"></param>
        /// <returns></returns>
        public Result Delete(string deviceid)
        {
            using var db = _dbContextFactory.CreateDbContext();
           var info=  db.DeviceInfos.Find(deviceid);
            if (info==null)
            {
                return Result.Reject("设备信息不存在");
            }
            info.IsDelete = true;
            return Result.From(db.SaveChanges(), s => s > 0);
        }
        /// <summary>
        /// 删除设备
        /// </summary>
        /// <param name="deviceid"></param>
        /// <returns></returns>
        public Result PhysicallyDelete(string deviceid)
        {
            try
            {
                using var db = _dbContextFactory.CreateDbContext();
                var info = db.DeviceInfos.Find(deviceid);
                if (info == null)
                {
                    return Result.Reject("设备信息不存在");
                }
                db.DeviceInfos.Remove(info);
                return Result.From(db.SaveChanges(), s => s > 0);
            }
            catch (Exception)
            {
                using var db = _dbContextFactory.CreateDbContext();
                var commandCount = db.CommandInfos.Where(p => p.DeviceInfoId == deviceid).Count();
                var alarmCount = db.AlarmInfos.Where(p => p.DeviceInfoId == deviceid).Count();
                var alarmHistoryCount = db.AlarmInfoHistorys.Where(p => p.DeviceInfoId == deviceid).Count();
                var propertiesCount = db.DevicePropertyInfos.Where(p => p.DeviceInfoId == deviceid).Count();
                var propertiesHistoryCount = db.DevicePropertyInfoHistorys.Where(p => p.DeviceInfoId == deviceid).Count();
                return Result.Reject($"无法删除,可能存在数据引用,其中 " +
                    $"命令:{commandCount}个,报警：{alarmCount}个,报警历史{alarmHistoryCount}个,属性数量:{propertiesCount}个,历史属性记录:{propertiesHistoryCount}个"
                    );
            }

        }
        /// <summary>
        /// 获取已删除的设备
        /// </summary>
        /// <returns></returns>
        public ResultData<DeviceInfo[]> DeletedDevice()
        {
            using var db = _dbContextFactory.CreateDbContext();
            var info = db.DeviceInfos.Where(p => p.IsDelete == true).Include(p=>p.PropertyInfos).Include(p=>p.AlarmInfos).ToArray();
            return ResultData<DeviceInfo[]>.Accept("查询成功",info);
        }
    }
}
